﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Flipmind.Xero;
using System.IO;
using LumenWorks.Framework.IO.Csv;

namespace XeroInvoiceLoaderApp
{
    public partial class EditInvoiceForm : Form
    {
        private Flipmind.Xero.XeroAPI api;
        private string invoiceID;
        private Invoice invoice;

        public EditInvoiceForm()
        {
            InitializeComponent();
        }

        public Invoice Invoice
        {
            get
            {

                return invoice;
            }
        }

        private InvoiceLineItem GetInvoiceLineItemFromListViewItem(ListViewItem li) {
            InvoiceLineItem line = new InvoiceLineItem();
            line.AccountCode = li.Text;
            line.Description = li.SubItems[1].Text;
            line.Quantity = Decimal.Parse(li.SubItems[2].Text);
            line.UnitAmount = Decimal.Parse(li.SubItems[3].Text);
            line.LineAmount = Decimal.Parse(li.SubItems[4].Text);
            line.TaxType = (TaxType)Enum.Parse(typeof(TaxType), li.SubItems[5].Text);
            line.TaxAmount = Decimal.Parse(li.SubItems[6].Text);
            //line.Tracking = new InvoiceLineItemTracking();
            return line;
        }

        public DialogResult ShowForm(Flipmind.Xero.XeroAPI api)
        {
            this.api = api;
            LoadDropdowns();
            invoice = new Invoice();
            invoice.Contact = new Contact();
            invoice.DueDate = DateTime.Now;
            invoice.InvoiceDate = DateTime.Now;
            LoadInvoice(invoice);
            return ShowDialog();
        }

        private void LoadDropdowns() {
            ddInvoiceType.Items.AddRange ( Enum.GetNames(typeof(InvoiceType)) );
            ddInvoiceStatus.Items.AddRange(Enum.GetNames(typeof(InvoiceStatus)));
        }

        public DialogResult ShowForm(Flipmind.Xero.XeroAPI api, string invoiceID)
        {
            LoadDropdowns();
            this.api = api;
            this.invoiceID = invoiceID;
            invoice = api.GetInvoiceById(invoiceID);
            LoadInvoice(invoice);
            return ShowDialog();
        }

        private void LoadInvoice(Invoice invoice)
        {
            txtInvoiceID.Text = invoice.InvoiceID;
            txtInvoiceNumber.Text = invoice.InvoiceNumber;
            ddInvoiceStatus.SelectedItem = invoice.InvoiceStatus.ToString();
            ddInvoiceType.SelectedItem = invoice.InvoiceType.ToString();
            txtInvoiceDate.Text = invoice.InvoiceDate.ToShortDateString();
            txtDueDate.Text = invoice.DueDate.ToString();
            txtReference.Text = invoice.Reference;
            txtSubTotal.Text = invoice.SubTotal.ToString();
            txtTotalTax.Text = invoice.TotalTax.ToString();
            txtTotal.Text = invoice.Total.ToString();
            chkIncludesTax.Checked = invoice.IncludesTax;
            //
            txtContactName.Text = invoice.Contact.Name;
            lvLineItems.Items.Clear();
            foreach (InvoiceLineItem line in invoice.LineItems)
            {
                AddInvoiceLineItem(line);
            }
        }

        private void EditInvoiceForm_Load(object sender, EventArgs e)
        {

        }

        private void btnViewContact_Click(object sender, EventArgs e)
        {
            EditContactForm frm = new EditContactForm();
            frm.ShowForm(invoice.Contact);
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            try
            {
                
                //invoice.Contact.Name = "Bob Limited";
                //invoice.LineItems = invoiceLineItems.ToArray();
                invoice.Reference = txtReference.Text;
                invoice.SubTotal = Decimal.Parse(txtSubTotal.Text);
                invoice.Total = Decimal.Parse(txtTotal.Text);
                invoice.TotalTax = Decimal.Parse(txtTotalTax.Text);
                invoice.DueDate = DateTime.Parse(txtDueDate.Text);
                invoice.IncludesTax = chkIncludesTax.Checked;
                invoice.InvoiceDate = DateTime.Parse(txtInvoiceDate.Text);
                invoice.InvoiceNumber = txtInvoiceNumber.Text;

                invoice.InvoiceStatus = (InvoiceStatus) Enum.Parse(typeof(InvoiceStatus), (string)ddInvoiceStatus.SelectedItem);
                invoice.InvoiceType = (InvoiceType)Enum.Parse(typeof(InvoiceType), (string)ddInvoiceType.SelectedItem);

                List<InvoiceLineItem> invoiceLineItems = new List<InvoiceLineItem>();
                invoice.LineItems.Clear();
                foreach (ListViewItem li in lvLineItems.Items)
                {
                    InvoiceLineItem line = GetInvoiceLineItemFromListViewItem(li);
                    invoice.LineItems.Add(line);
                }

                try
                {
                    Invoice newInvoice = api.CreateInvoice(invoice);
                    MessageBox.Show("Invoice Created");
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Problem creating invoice: " + ex);
                    return;
                }
                DialogResult = DialogResult.OK;
                Close();   
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
                return;
            }            
        }

        private void UpdateInvoiceLineItem(ListViewItem li, InvoiceLineItem line)
        {
            li.SubItems.Clear();
            li.Text = line.AccountCode;
            li.SubItems.Add(line.Description);
            li.SubItems.Add(line.Quantity.ToString());
            li.SubItems.Add(line.UnitAmount.ToString());
            li.SubItems.Add(line.LineAmount.ToString());
            li.SubItems.Add(line.TaxType.ToString());
            li.SubItems.Add(line.TaxAmount.ToString());
            if (line.Tracking != null)
            {
                li.SubItems.Add(line.Tracking.Name);
            }
        }

        private void AddInvoiceLineItem(InvoiceLineItem line)
        {
            ListViewItem li = lvLineItems.Items.Add("");
            UpdateInvoiceLineItem(li, line);

        }

        private void btnAddLineItem_Click(object sender, EventArgs e)
        {
            EditInvoiceLineItemForm frm = new EditInvoiceLineItemForm();
            InvoiceLineItem item = frm.ShowForm(api);
            if (item != null)
            {
                AddInvoiceLineItem(item);
            }
        }

        private void lvLineItems_DoubleClick(object sender, EventArgs e)
        {
            EditInvoiceLineItemForm frm = new EditInvoiceLineItemForm();
            if (lvLineItems.SelectedItems.Count > 0) {
                ListViewItem li = lvLineItems.SelectedItems[0];
                InvoiceLineItem lineItem = GetInvoiceLineItemFromListViewItem(li);
                InvoiceLineItem newItem = frm.ShowForm(api, lineItem);
                if (newItem != null)
                {
                    UpdateInvoiceLineItem(li, newItem);
                }
            }
        }

        private void btnLoadLineItems_Click(object sender, EventArgs e)
        {
            try
            {
                DialogResult result = openFileDialog1.ShowDialog();
                if (result == DialogResult.OK)
                {
                    decimal subTotal = 0;
                    decimal total = 0;
                    decimal taxTotal=0;
                    // open the file "data.csv" which is a CSV file with headers
                    using (CsvReader csv = new CsvReader(new StreamReader(openFileDialog1.FileName), true))
                    {
                        int fieldCount = csv.FieldCount;
                        string[] headers = csv.GetFieldHeaders();

                        while (csv.ReadNextRecord())
                        {
                            string accountCode = csv["AccountCode"];
                            string description = csv["Description"];
                            string quantity = csv["Quantity"];
                            string unit = csv["Unit"];
                            string amount = csv["Amount"];
                            string taxType = csv["TaxType"];
                            string taxAmount = csv["TaxAmount"];
                            InvoiceLineItem line = new InvoiceLineItem();
                            line.AccountCode = accountCode;
                            line.Description = description;
                            line.Quantity = Decimal.Parse(quantity);
                            line.UnitAmount = decimal.Parse(unit);
                            line.LineAmount = decimal.Parse(amount);
                            if (!String.IsNullOrEmpty(taxType))
                            {
                                line.TaxType = (TaxType)Enum.Parse(typeof(TaxType), taxType);
                            }
                            else
                            {
                                line.TaxType = TaxType.None;
                            }
                            if (!string.IsNullOrEmpty(taxAmount))
                            {
                                line.TaxAmount = decimal.Parse(taxAmount);
                            }
                            total+=line.LineAmount + line.TaxAmount;
                            subTotal +=line.LineAmount;
                            taxTotal+=line.TaxAmount;

                            AddInvoiceLineItem(line);
                            //for (int i = 0; i < fieldCount; i++)
                            //{
                             //   Console.Write(string.Format("{0} = {1};", headers[i], csv[i]));
                            //}
                            //Console.WriteLine();
                        }
                    }
                    txtTotal.Text = total.ToString();
                    txtTotalTax.Text = taxTotal.ToString();
                    txtSubTotal.Text = subTotal.ToString(); 

                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Problem loading CSV." + ex);
            }
        }
    }
}
